#include <iostream>
#include <vector>
#include <cassert>
#include <unordered_map>
#include <queue>
#include <string>

using namespace std;
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:

    int lengthOfLongestSubstring(string s) {
        int freq[256] = {0};
        int left = 0, right = -1;
        int res = 0;
        while (left < s.size()){
            if (right + 1 < s.size() && freq[s[right+1]] == 0){
                freq[s[++right]] ++;
            } else{
                freq[s[left++]]--;
            }
            res = max(res, right - left + 1);
        }
        return res;
    }

    int minSubArrayLen(int s, vector<int>& nums) {

        int left = 0, right = -1;
        int sum = 0;
        int res = nums.size() + 1;
        while (left < nums.size()){
            if (right + 1 < nums.size() && sum < s){
                sum += nums[++right];
            } else{
                sum -= nums[left++];
            }
            if (sum >= s){
                res = min(res, right - left + 1);
            }
        }
        if (res == nums.size()+1){
            return 0;
        }
        return res;
    }

    vector<int> twoSumL(vector<int>& numbers, int target){
        int left = 0, right = numbers.size() - 1;
        while (left < right){
            if (numbers[left] + numbers[right] == target){
                int res[2] = {left, right};
                return vector<int>(res, res + 2);
            } else if (numbers[left] + numbers[right] < target){
                left++;
            } else{
                right--;
            }
        }
    }

    void sortColor(vector<int>& nums){
        
        int zero = -1;
        int two = nums.size();
        for (int i = 0; i < two;) {
            if (nums[i] == 1)
                i ++;
            else if (nums[i] == 2){
                two --;
                swap(nums[i], nums[two]);
            } else{
                zero ++;
                swap(nums[i], nums[zero]);
                i ++;
            }
        }

    }

    void sortColor2(vector<int>& nums){
        int count[3] = {0};
        for (int i = 0; i < nums.size(); i++) {
            assert(nums[i] >= 0 && nums[i] <= 2);
            count[nums[i]]++;
        }

        int index = 0;
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < count[j]; k++) {
                nums[index++] = j;
            }
        }
    }

    vector<int> twoSum(vector<int>& nums, int target){
        unordered_map<int, int> record;
        for (int i = 0; i < nums.size(); i++) {
            int complement = target - nums[i];
            if (record.find(complement) != record.end()){
                int res[2] = {i, record[complement]};
                return vector<int>(res, res+2);
            }
            record[nums[i]] = i;
        }
    }

    int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D){

        unordered_map<int, int> record;
        for (int i = 0; i < A.size(); i++) {
            for (int j = 0; j < B.size(); j++) {
                record[A[i] + B[j]] ++;
            }
        }
        int res = 0;
        for (int i = 0; i < C.size(); i++) {
            for (int j = 0; j < D.size(); j++) {
                if (record.find(0 - C[i] - D[j]) != record.end()){
                    res += record[0-C[i]-D[j]];
                }
            }
        }
        return res;
    }

    int numberOfBoomerangs(vector<pair<int, int>>& points){
        int res = 0;
        for (int i = 0; i < points.size(); i++) {
            unordered_map<int, int > record;
            for (int j = 0; j < points.size(); j++) {
                if (j != i)
                    record[dis(points[i], points[j])] ++;
            }
            for(unordered_map<int, int>::iterator iter = record.begin(); iter != record.end(); iter++){
                if (iter->second >= 2){
                    res += (iter->second)*(iter->second-1);
                }
            }
        }
        return res;
    }

    int numSquares(int n){
        queue<pair<int,int>> q;
        q.push(make_pair(n, 0));

        vector<bool> visited(n+1, false);
        visited[n] = true;

        while (!q.empty()){
            int num = q.front().first;
            int step = q.front().second;
            q.pop();
            for (int i = 1; ; i++) {
                int a = num - i * i;
                if (a < 0)
                    break;
                if (a == 0)
                    return step + 1;
                if (!visited[a]){
                    q.push(make_pair(a, step+1));
                }
            }

        }
    }

    vector<int> topKFrequent(vector<int>& nums, int k) {

        unordered_map<int, int> freq;
        for (int i = 0; i < nums.size(); i ++) {
            freq[nums[i]] ++;
        }
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
        for (unordered_map<int, int>::iterator iter = freq.begin(); iter != freq.end(); iter ++) {
            if (pq.size() == k){
                if (iter->second > pq.top().first){
                    pq.pop();
                    pq.push(make_pair(iter->second, iter->first));
                }
            } else{
                pq.push(make_pair(iter->second, iter->first));
            }
        }
        vector<int> res;
        while (!pq.empty()){
            res.push_back(pq.top().second);
            pq.pop();
        }
        return res;
    }

    int maxDepth(TreeNode* root) {
        if (root == NULL){
            return 0;
        }
        return max(maxDepth(root->left), maxDepth(root->right)) + 1;;
    }

    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL){
            return NULL;
        }
        invertTree(root->left);
        invertTree(root->right);
        swap(root->left, root->right);
        return root;
    }

    bool hasPathSum(TreeNode* root, int sum) {
        if (root == NULL)
            return false;
        if (root->left == NULL && root->right == NULL)
            return root->val == sum;
        if (hasPathSum(root->left, sum - root->val))
            return true;
        if (hasPathSum(root->right, sum - root->val))
            return true;
        return false;
    }

    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> res;
        if (root == NULL)
            return res;

        if (root->left == NULL && root->right == NULL){
            res.push_back(root->val+"");
            return res;
        }

        vector<string> leftS = binaryTreePaths(root->left);
        for (int i = 0; i < leftS.size(); i++) {
            res.push_back(root->val + "->" + leftS[i]);
        }

        vector<string> rightS = binaryTreePaths(root->right);
        for (int i = 0; i < rightS.size(); i++) {
            res.push_back(root->val + "->" + rightS[i]);
        }

        return res;
    }

    vector<string> binaryTreePaths2(TreeNode* root) {

        vector<string> res;

        if(root == NULL)
            return res;

        if(root->left == NULL && root->right == NULL){
            res.push_back(to_string(root->val));
            return res;
        }

        vector<string> leftPaths = binaryTreePaths(root->left);
        for(int i = 0 ; i < leftPaths.size() ; i ++)
            res.push_back(to_string(root->val) + "->" + leftPaths[i]);

        vector<string> rightPaths = binaryTreePaths(root->right);
        for(int i = 0 ; i < rightPaths.size() ; i ++)
            res.push_back(to_string(root->val) + "->" + rightPaths[i]);

        return res;
    }

private:
    int dis(const pair<int, int>& pa, const pair<int, int>& pb){
        return (pa.first - pb.first) * (pa.first - pb.first) + (pa.second - pb.second) * (pa.second - pb.second);
    }

};
int main() {

    int nums[] = {2, 3, 1, 2, 4, 3};

    int target = 7;

    vector<pair<int,int> >vec;
    vec.push_back(make_pair<int, int>(0, 0));
    vec.push_back(make_pair<int, int>(1, 0));
    vec.push_back(make_pair<int, int>(2, 0));

    int i = Solution().numberOfBoomerangs(vec);
    cout << i<< endl;

    return 0;
}